/*
 * Copyright � 2008 Nokia Corporation.
 */


#include "SudokuMenuControl.h"
#include "SudokuAppView.h"
#include "SudokuGridControl.h"
#include "SudokuGameLogic.h"
#include "SudokuAppUi.h"
#include "SudokuStatisticControl.h"

#include <fbs.h>
#include <eikenv.h>

CSudokuMenuControl::CSudokuMenuControl (CSudokuContainerControl& aParent, CFbsBitGc*& aBgc)
:iBgc(aBgc),iParent(aParent)
    {
    // No implementation required
    }

CSudokuMenuControl::~CSudokuMenuControl ()
    {
    iStringArray->Reset();
    delete iStringArray;
    }

CSudokuMenuControl* CSudokuMenuControl::NewLC (CSudokuContainerControl& aParent, CFbsBitGc*& aBgc)
    {
    CSudokuMenuControl* self = new (ELeave)CSudokuMenuControl(aParent, aBgc);
    CleanupStack::PushL (self );
    self->ConstructL ();
    return self;
    }

CSudokuMenuControl* CSudokuMenuControl::NewL (CSudokuContainerControl& aParent, CFbsBitGc*& aBgc)
    {
    CSudokuMenuControl* self=CSudokuMenuControl::NewLC (aParent, aBgc);
    CleanupStack::Pop ( ); // self;
    return self;
    }

void CSudokuMenuControl::ConstructL()
    {
    SetContainerWindowL(iParent);
    iStringArray = new (ELeave) CDesCArrayFlat(5);
    }

void CSudokuMenuControl::AddMenuItemL(TDesC& aItem)
    {
    iStringArray->AppendL(aItem);
    }

void CSudokuMenuControl::SetObserver(MSudokuMenuControlObserver* aObserver)
    {
    iObserver = aObserver;
    }

void CSudokuMenuControl::Draw( const TRect& /*aRect*/ ) const
    {
    // Remember to draw into backbuffer iBgc
    DrawItems();
    }

void CSudokuMenuControl::DrawItems() const
    {
    iParent.UseFont(iParent.StatisticFont());
    TInt txtHeight = iParent.StatisticFont()->HeightInPixels();
    
    // Draw background
    TRgb customBlack = TRgb(255,243,206);
    customBlack.SetAlpha(90);
    iBgc->SetBrushStyle(CGraphicsContext::ESolidBrush);
    iBgc->SetBrushColor(customBlack);
    iBgc->DrawRect(Rect());
  
    // Draw menu
    iBgc->SetPenColor(KRgbBlack);
    
    TPoint itemTl = Rect().iTl;
    itemTl.iX += KItemCap;
    itemTl.iY += KItemCap;
    TRect itemRect(itemTl,TSize(iItemWidth,iItemHeight));
    for (TInt i=0 ; i<iStringArray->Count() ; i++)
        {
        // Draw item rect
        if (iActiveItem == i)
            {
            iBgc->SetBrushColor(TRgb(173,146,115));
            }
        else
            {
            iBgc->SetBrushColor(TRgb(255,243,206));
            }
        iBgc->DrawRoundRect(itemRect,TSize(4,4));

        // Draw item text
        TPtrC16 ptr = (*iStringArray)[i];
        TInt txtWidth = iParent.StatisticFont()->TextWidthInPixels(ptr);
        TPoint textPoint = itemRect.iTl;
        textPoint.iY += (iItemHeight - txtHeight);
        textPoint.iX += ((Rect().Width() - txtWidth) /2) - KItemCap; 
        iBgc->DrawText(ptr,textPoint);

        itemRect.Move(0,iItemHeight);
        itemRect.Move(0,KItemCap);
        }
    
    
    iBgc->SetBrushStyle(CGraphicsContext::ENullBrush);
    }


TSize CSudokuMenuControl::MiniSizeNeeded()
    {
    TSize min;
    // Calculate font sizes
    TInt txtHeight = iParent.StatisticFont()->HeightInPixels();
    TInt txtWidth = iParent.StatisticFont()->TextWidthInPixels(_L("A"));
    
    // Find longist word
    TInt wordLen = 0;
    for (TInt i=0 ; i<iStringArray->Count() ; i++)
        {
        TPtrC16 ptr = (*iStringArray)[i];
        if (ptr.Length() > wordLen)
            {
            wordLen = ptr.Length(); 
            }
        }
    // Set minimum width for the menu
    min.iWidth = wordLen * txtWidth + KItemCap*4;
    // Set minimum height for the menu
    min.iHeight = iStringArray->Count() * (txtHeight + KItemCap + KItemCap) + KItemCap + KHeightTuning;
    return min;
    }

void CSudokuMenuControl::SizeChanged()
    {
    TRect rect = Rect();
    iItemHeight = rect.Height() / iStringArray->Count();
    iItemHeight -= KHeightTuning;
    iItemWidth = rect.Width() - KItemCap*2;
    iActiveItem=0;
    }

TKeyResponse CSudokuMenuControl::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
    {
    TKeyResponse ret = EKeyWasNotConsumed;
    TInt number = KErrNotFound;
    
    if (aType == EEventKeyDown)
        {
        switch (aKeyEvent.iScanCode)
            {
            case EStdKeyUpArrow:
                {
                if (iActiveItem > 0)
                    {
                    iActiveItem--;
                    }
                ret = EKeyWasConsumed;
                break;
                }
            case EStdKeyDownArrow:
                {
                if (iActiveItem < iStringArray->Count()-1)
                    {
                    iActiveItem++;
                    }
                ret = EKeyWasConsumed;
                break;
                }
            case EStdKeyDevice3: // Center key
            case EStdKeyDevice0: // Select key
                {
                MakeVisible(EFalse);
                if (iObserver)
                    {
                    iObserver->MenuItemSelected(iActiveItem);
                    }
                return EKeyWasConsumed;
                }
            default:
                {
                break;
                }
            };
        }
    
    return ret;
    }

void CSudokuMenuControl::HitActimeMenuItem()
    {
    MakeVisible(EFalse);
    if (iObserver)
        {
        iObserver->MenuItemSelected(iActiveItem);
        }
    }


void CSudokuMenuControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
    {
    if (aPointerEvent.iType == TPointerEvent::EButton1Down)
        {
        TPoint pos = aPointerEvent.iPosition;
        TInt y = pos.iY - Rect().iTl.iY;
        if (y > iItemHeight + KHeightTuning)
            {
            iActiveItem = y / (iItemHeight + KHeightTuning);
            }
        else
            {
            iActiveItem = 0;
            }
        }
    else if (aPointerEvent.iType == TPointerEvent::EButton1Up)
        {
        MakeVisible(EFalse);
        if (iObserver)
            {
            iObserver->MenuItemSelected(iActiveItem);
            }
        }
    }

void CSudokuMenuControl::MakeVisible(TBool aVisible)
    {
    if (aVisible)
        {
        iParent.StatisticControl()->StopGameTimer();
        static_cast<CSudokuAppUi*>(iEikonEnv->EikAppUi())->UseSelectBackCbaL();
        }
    else
        {
        iParent.StatisticControl()->ContinueGameTimer();
        static_cast<CSudokuAppUi*>(iEikonEnv->EikAppUi())->UseOptionsExitCbaL();
        }
    CCoeControl::MakeVisible(aVisible);
    }

